#include "sys_uart.h"
#include "sys_clock.h"
#include "sys_gpio.h"
#include "sys_delay.h"
#include "sys_cache.h"
#include "sys_interrupt.h"
#include "sys_timer.h"
#include <string.h>
#include <stdio.h>
#include <sys_mmu.h>
#include "sys_dma.h"

/********************************************/
// UART0   输出打印信息
// UART1,2 做DMA收发测试
// 测试正常...
/********************************************/

__align(4) DMA uart1_rx_dma;
__align(4) DMA uart2_rx_dma;
__align(4) DMA uart1_tx_dma;
__align(4) DMA uart2_tx_dma;

__align(4) char uart1_rx_buff[200];
__align(4) char uart2_rx_buff[200];
__align(4) char uart1_tx_buff[200];
__align(4) char uart2_tx_buff[200];
/*---------------------------------------------------
配置uart_rx_dma
uart 串口号
dma  dma号
des_addr 内存地址
bcnt 接收中断计数
----------------------------------------------------*/
int uart_rx_dma_config(enum eUart uart, int dma, DMA *uart_rx_dma, unsigned int rx_addr, int bcnt)
{
	u32_t addr = 0, DRQ_Type;
	sysprintf("uart_rx_dma_config...\r\n");
	if (uart == UART0)
	{
		addr = UART0_ADDR;
		DRQ_Type = NDMAS_DRQ_Type_UART0_Rx;
	}
	else if (uart == UART1)
	{
		addr = UART1_ADDR;
		DRQ_Type = NDMAS_DRQ_Type_UART1_Rx;
	}
	else if (uart == UART2)
	{
		addr = UART2_ADDR;
		DRQ_Type = NDMAS_DRQ_Type_UART2_Rx;
	}
	//-----------
	uart_rx_dma->Type = NDMA;				   // 类型
	uart_rx_dma->Ch = dma;					   // 通道
	uart_rx_dma->Byte_Counter = bcnt;		   // Byte计数
	uart_rx_dma->Continuous_Mode_Enable = 1;   // 连续模式
	uart_rx_dma->Read_Byte_Counter_Enable = 0; // 读计数值使能
	//---------
	uart_rx_dma->Source_Address = (unsigned int)(addr + 0x00); // 源地址
	uart_rx_dma->Source_Address_Type = DMA_ADDRESS_TYEP_IO;	   // 源地址类型
	uart_rx_dma->Source_DRQ_Type = DRQ_Type;				   // 源类型
	uart_rx_dma->Source_Data_Width = DMA_DATA_WIDTH_8;		   // 源数据宽度
	uart_rx_dma->Source_Burst_Length = DMA_BURST_LENGTH_1;	   // BURST
	//-----------
	uart_rx_dma->Destination_Address = (unsigned int)(rx_addr);		 // 目标地址
	uart_rx_dma->Destination_Address_Type = DMA_ADDRESS_TYEP_LINEER; // 目标地址类型
	uart_rx_dma->Destination_DRQ_Type = NDMAD_DRQ_Type_SDRAM_Memory; // 目标类型
	uart_rx_dma->Destination_Data_Width = DMA_DATA_WIDTH_8;			 // 目标数据宽度
	uart_rx_dma->Destination_Burst_Length = DMA_BURST_LENGTH_1;		 // BURST
	DMA_Config(uart_rx_dma);
	DMA_Interrupt_Control_Full(uart_rx_dma, 1);
	DMA_Enable(uart_rx_dma);
	return 0;
}
/*---------------------------------------------------
配置uart_tx_dma
uart 串口号
dma  dma号
des_addr 内存地址
bcnt 发送中断计数
----------------------------------------------------*/
int uart_tx_dma_config(enum eUart uart, int dma, DMA *uart_tx_dma, unsigned int tx_addr, int bcnt)
{
	u32_t addr = 0, DRQ_Type;
	// sysprintf("uart_tx_dma_config...\r\n");
	if (uart == UART0)
	{
		addr = UART0_ADDR;
		DRQ_Type = NDMAD_DRQ_Type_UART_Tx;
	}
	else if (uart == UART1)
	{
		addr = UART1_ADDR;
		DRQ_Type = NDMAD_DRQ_Type_UART1_Tx;
	}
	else if (uart == UART2)
	{
		addr = UART2_ADDR;
		DRQ_Type = NDMAD_DRQ_Type_UART2_Tx;
	}
	//-----------
	uart_tx_dma->Type = NDMA;				   // 类型
	uart_tx_dma->Ch = dma;					   // 通道
	uart_tx_dma->Byte_Counter = bcnt;		   // Byte计数
	uart_tx_dma->Continuous_Mode_Enable = 0;   // 连续模式
	uart_tx_dma->Read_Byte_Counter_Enable = 0; // 读计数值使能
	//---------
	uart_tx_dma->Source_Address = (unsigned int)(tx_addr);		// 源地址
	uart_tx_dma->Source_Address_Type = DMA_ADDRESS_TYEP_LINEER; // 源地址类型
	uart_tx_dma->Source_DRQ_Type = NDMAD_DRQ_Type_SDRAM_Memory; // 源类型
	uart_tx_dma->Source_Data_Width = DMA_DATA_WIDTH_8;			// 源数据宽度
	uart_tx_dma->Source_Burst_Length = DMA_BURST_LENGTH_1;		// BURST
	//-----------
	uart_tx_dma->Destination_Address = (unsigned int)(addr + 0x00); // 目标地址
	uart_tx_dma->Destination_Address_Type = DMA_ADDRESS_TYEP_IO;	// 目标地址类型
	uart_tx_dma->Destination_DRQ_Type = DRQ_Type;					// 目标类型
	uart_tx_dma->Destination_Data_Width = DMA_DATA_WIDTH_8;			// 目标数据宽度
	uart_tx_dma->Destination_Burst_Length = DMA_BURST_LENGTH_1;		// BURST
	DMA_Config(uart_tx_dma);
	DMA_Interrupt_Control_Full(uart_tx_dma, 1);
	DMA_Enable(uart_tx_dma);
	return 0;
}
/*---------------------------------------------------
dma中断
----------------------------------------------------*/
void DMA_ISR(void)
{
	int i;
	if (DMA_Get_Full_TIP(&uart1_rx_dma)) // 接收完成中断
	{
		sysInvalidCache(); // 数据更新
		sysprintf("UART1:");
		for (i = 0; i < 10; i++)
		{
			sysprintf("%02x,", uart1_rx_buff[i]);
		}
		sysprintf("\r\n");
	}
	if (DMA_Get_Full_TIP(&uart2_rx_dma)) // 接收完成中断
	{
		sysInvalidCache(); // 数据更新
		sysprintf("UART2:");
		for (i = 0; i < 10; i++)
		{
			sysprintf("%02x,", uart2_rx_buff[i]);
		}
		sysprintf("\r\n");
	}
	if (DMA_Get_Full_TIP(&uart1_tx_dma)) // 发送完成中断
	{
		sysprintf("u1tx\r\n");
	}
	if (DMA_Get_Full_TIP(&uart2_tx_dma)) // 发送完成中断
	{
		sysprintf("u2tx\r\n");
	}
}
/*---------------------------------------------------
---- main
---- main
----------------------------------------------------*/

int main(void)
{
	int i = 0;
	Sys_Clock_Init(408000000);
	sys_mmu_init();

	Sys_Uart_Init(UART0, 408000000, 115200, 0);
	Sys_Uart_Init(UART1, 408000000, 115200, 0);
	Sys_Uart_Init(UART2, 408000000, 115200, 0);

	Sys_SET_UART_DBG(UART0);

	// 配置dma
	DMA_Init();

	uart_rx_dma_config(UART0, 0, &uart1_rx_dma, (unsigned int)uart1_rx_buff, 10); // DMA 接收初始化
	// uart_rx_dma_config(UART2, 1, &uart2_rx_dma, (unsigned int)uart2_rx_buff, 10); // DMA 接收初始化

	IRQ_Init(IRQ_LEVEL_1, IRQ_DMA, DMA_ISR, 3);
	sysSetLocalInterrupt(ENABLE_IRQ);

	sysprintf("\r\n\r\n\r\n");
	sysprintf("Sys_Start...\r\n");
	sysprintf("Dram Init Size %d Mb.\r\n", 32);
	sysprintf("UART_DMA_TEST...\r\n");

	delay_ms(1000);

	while (1) // DMA 发送测试
	{
		for (i = 0; i < 20; i++)
		{
			uart1_tx_buff[i] = 0x30 + i;
		}
		// for (i = 0; i < 20; i++)
		// {
		// 	uart2_tx_buff[i] = 0x30 + i;
		// }
		uart_tx_dma_config(UART0, 2, &uart1_tx_dma, (unsigned int)uart1_tx_buff, 20);
		delay_ms(1000);
		// uart_tx_dma_config(UART2, 3, &uart2_tx_dma, (unsigned int)uart2_tx_buff, 20);
		// delay_ms(1000);
		for (i = 0; i < 20; i++)
		{
			uart1_tx_buff[i] = 0x40 + i;
		}
		// for (i = 0; i < 20; i++)
		// {
		// 	uart2_tx_buff[i] = 0x40 + i;
		// }
		uart_tx_dma_config(UART0, 2, &uart1_tx_dma, (unsigned int)uart1_tx_buff, 20);
		delay_ms(1000);
		// uart_tx_dma_config(UART2, 3, &uart2_tx_dma, (unsigned int)uart2_tx_buff, 20);
		// delay_ms(1000);
	}
	return 0;
}
